﻿using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;

using Cratos.Desktop;
using System.Windows;
using Cratos.Tools.General;
using Cratos.Generator.DataObject;

namespace Cratos.Generator
{
	/// <summary>
	/// Cratos Project Presenter class
	/// </summary>
	public class CratosProjectPresenter : MVPCrudPresenter<CratosProjectView>
	{
		#region Class Constant declarations
		#endregion

		#region Class Event declarations
		/// <summary>
		/// Progress Start event
		/// </summary>
		public event MVPProgressEvent ProgressStart;

		/// <summary>
		/// Progress End event
		/// </summary>
		public event MVPProgressEvent ProgressEnd;

		/// <summary>
		/// Progress Update event
		/// </summary>
		public event MVPProgressUpdateEvent ProgressUpdate;
		#endregion

		#region Class Variable declarations
		private ApplicationPresenter	m_AppPresenter;
		private DOCratosProject				m_Project;
		#endregion

		#region Class Constructors & Destructors
		/// <summary>
		/// Class Constructor
		/// </summary>
		/// <param name="appPresenter">Application Presenter</param>
		/// <param name="currentView">Current View</param>
		public CratosProjectPresenter(ApplicationPresenter appPresenter, CratosProjectView currentView)
			: base(currentView, "Cratos Project")
		{
			// Save the relevant values
			this.m_AppPresenter		= appPresenter;
			currentView.Presenter = this;

			// Create the relevant objects
			this.m_Project = new DOCratosProject();

			// Set the relevant CRUD options
			this.CanCreate = this.Project.CanCreate;
			this.CanModify = this.Project.CanUpdate;
			this.CanDelete = this.Project.CanDelete;
		}
		#endregion

		#region Class Properties
		/// <summary>
		/// Current Project
		/// </summary>
		public DOCratosProject Project
		{
			get { return (this.m_Project); }
			set { this.m_Project = value; }
		}

		/// <summary>
		/// Application Presenter
		/// </summary>
		public ApplicationPresenter ApplicationPresenter
		{
			get { return (this.m_AppPresenter); }
		}
		#endregion

		#region Class Methods
		/// <summary>
		/// Load a Project
		/// </summary>
		/// <param name="projectID">Project ID</param>
		/// <returns>A boolean indicating the success of the method</returns>
		public bool LoadProject(long projectID)
		{
			// Declare the required variables
			bool returnValue = false;

			try
			{
				// Start the progress
				this.OnProgressStart();

				// Update the Progress
				this.OnProgressUpdate("Starting Project Load");

				// Clear all relevant data
				this.Errors.Clear();

				// Create and Setup the relevant Data Object
				this.Project          = new DOCratosProject();
				this.Project.Id       = projectID;
				this.Project.DOAction = DOCratosAction.Retrieve;

				// Update the Progress
				this.OnProgressUpdate("Sending request to server");

				// Perform the required action
				if (this.Project.PerformAction())
				{
					// Update the Progress
					this.OnProgressUpdate("Processing response from server");

					// Make sure we have data to work with
					if (this.Project.DOActionResult == DOCratosActionResult.Success)
					{
						// Update the relevant object(s)
						this.OnNotifyPropertyChanged("Project");

						// Set the successful return value
						returnValue = true;
					}
				}
				else
				{
					// Process any errors
					foreach (CratosError currentError in this.Project.Errors) { this.Errors.Add(currentError); }
				}
			}
			catch (Exception runtimeException)
			{
				// Log and Display the error
				CratosHelper.LogMessage(CratosLogSeverity.Exception, "ProjectPresenter.LoadProject",
																"A runtime error occurred", runtimeException, true);
			}
			finally
			{
				// End the progress
				this.OnProgressEnd();
			}

			// Display the required error
			if (this.Errors.Count > 0) { this.DisplayError("Project Load"); }

			// Return to calling method
			return(returnValue);
		}

		/// <summary>
		/// Validate the relevant object
		/// </summary>
		/// <returns>A boolean value indicating the success of the method</returns>
		public bool Validate()
		{
			// Declare the required variables
			bool returnValue = true;

			// Clear all pending errors
			this.Errors.Clear();

			// Validate the relevant fields
			if (string.IsNullOrEmpty(this.Project.Name))
			{
				this.Errors.Add(new CratosError("Project", CratosLogSeverity.ValidationError, "Project Name is mandatory"));
				returnValue = false;
			}

			// return to calling method
			return (returnValue);
		}

		/// <summary>
		/// Modify an existing item
		/// </summary>
		public void Modify()
		{
			// Declare the required variables

			// Set the current item's action
			this.Project.DOAction = DOCratosAction.Update;

			// Update the relevant indicators
			this.IsInEdit  = true;
			this.CanModify = false;
			this.CanDelete = false;

			// Set the focus
			this.View.m_TxtProjectName.Focus();

			// Return to calling method
			return;
		}

		/// <summary>
		/// Delete the currently selected item
		/// </summary>
		public void Delete()
		{
			// Declare the required variables

			// Request Confirmation from user
			if (MessageBox.Show("Are you sure you want delete the Selected User?", "Cratos Project",
													MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK)
			{
				//  try
				//  {
				//    // Start the progress
				//    this.OnProgressStart();

				//    // Update the Progress
				//    this.OnProgressUpdate("Preparing to send request to server");

				//    // Create and setup the relevant objects
				//    cdoUser = new CdoRaptor<DOCuratioUser>();
				//    cdoUser.DataObject = this.CurrentUser;
				//    cdoUser.DataObject.DOAction = DORaptorAction.Delete;

				//    // Update the Progress
				//    this.OnProgressUpdate("Sending request to server");

				//    // Send the request to the server
				//    if (cdoUser.PerformAction())
				//    {
				//      // Update the Progress
				//      this.OnProgressUpdate("Processing response from server");

				//      // Update the relevant indicators
				//      this.IsInEdit = false;

				//      // Reload the list
				//      this.LoadAllUsers();
				//    }
				//    else
				//    {
				//      // Update the errors
				//      foreach (string currentError in cdoUser.Errors) { this.Errors.Add(currentError); }
				//    }
				//  }
				//  catch (Exception runtimeException)
				//  {
				//    // Display the exception
				//    RaptorHelper.LogMessage(RaptorLogSeverity.Exception, "User Administration [Delete]",
				//                            "Unhandled exception occurred", runtimeException, true);
				//  }
				//  finally
				//  {
				//    // End the progress
				//    this.OnProgressEnd();
				//  }
			}

			// Return to calling method
			return;
		}

		/// <summary>
		/// Save all pending changes
		/// </summary>
		/// <returns>A boolean value indicating success</returns>
		public bool Save()
		{
			// Declare the required variables
			bool returnValue = false;

			try
			{
				//// Start the progress
				//this.OnProgressStart();

				//// Update the Progress
				//this.OnProgressUpdate("Validating the relevant data");

				//// Validate the entry fields
				//if (this.Validate())
				//{
				//  // Update the Progress
				//  this.OnProgressUpdate("Sending request to server");

				//  // Send the request to the server
				//  if (this.Project.PerformAction())
				//  {
				//    // Update the Progress
				//    this.OnProgressUpdate("Processing response from server");

				//    // Update the relevant indicators
				//    this.IsInEdit = false;

				//    // Set the successful return value
				//    returnValue = true;

				//    // End the progress
				//    this.OnProgressEnd();
				//  }
				//  else
				//  {
				//    // Update the errors
				//    foreach (CratosError currentError in this.Project.Errors) { this.Errors.Add(currentError); }
				//  }
				//}
			}
			catch (Exception runtimeException)
			{
				// Display the exception
				CratosHelper.LogMessage(CratosLogSeverity.Exception, "Project [Save]",
																"Unhandled exception occurred", runtimeException, true);
			}

			// Display the error message if required
			if (!returnValue) { this.DisplayError("Project"); }

			// Return to calling method
			return (returnValue);
		}

		/// <summary>
		/// Cancel all pending changes
		/// </summary>
		public void Cancel()
		{
			// Declare the required variables

			// Update the relevant indicators
			this.IsInEdit  = false;
			this.CanModify = this.Project.CanUpdate;
			this.CanDelete = this.Project.CanDelete;

			// Handle the relevant action
			if (this.Project.DOAction == DOCratosAction.Create)
			{
				this.Project = new DOCratosProject();
				this.OnNotifyPropertyChanged("Project");
			}
			else { this.LoadProject(this.Project.Id); }

			// Return to calling method
			return;
		}
		#endregion

		#region Class Support Methods
		#endregion
	}
}
